/**
 * 实验报告目录扫描器
 * 用于扫描和解析实验报告目录结构
 */
import logger from './Logger';

class ReportDirectoryScanner {
  /**
   * 扫描实验报告目录
   * @param {string} directoryPath - 目录路径
   * @param {Array} students - 学生列表
   * @returns {Object} 扫描结果，包含文件列表和异常信息
   */
  static async scanDirectory(directoryPath, students) {
    try {
      logger.info(`开始扫描实验报告目录: ${directoryPath}`);

      // 在前端环境中，我们无法直接访问文件系统
      // 这里模拟扫描过程，实际应用中需要通过后端API实现
      const result = await this.simulateScan(directoryPath, students);

      logger.info(`实验报告目录扫描完成，共发现 ${result.files.length} 个文件`);
      return result;
    } catch (error) {
      logger.error('扫描实验报告目录失败', error);
      throw error;
    }
  }

  /**
   * 模拟扫描过程
   * @param {string} directoryPath - 目录路径
   * @param {Array} students - 学生列表
   * @returns {Object} 扫描结果
   */
  static async simulateScan(directoryPath, students) {
    // 模拟文件列表
    // 在实际应用中，这里应该通过API获取目录结构
    const mockFiles = [
      { name: '实验1_2021001_张三.xlsx', path: `${directoryPath}/班级1/实验1/实验1_2021001_张三.xlsx` },
      { name: '实验1_2021002_李四.xlsx', path: `${directoryPath}/班级1/实验1/实验1_2021002_李四.xlsx` },
      { name: '实验1_2021003_王五.xlsx', path: `${directoryPath}/班级1/实验1/实验1_2021003_王五.xlsx` },
      { name: '实验2_2021001_张三.xlsx', path: `${directoryPath}/班级1/实验2/实验2_2021001_张三.xlsx` },
      { name: '实验2_2021002_李四.xls', path: `${directoryPath}/班级1/实验2/实验2_2021002_李四.xls` },
      { name: '实验3_2021001_张三.csv', path: `${directoryPath}/班级1/实验3/实验3_2021001_张三.csv` },
      { name: '实验1_2022001_赵六.xlsx', path: `${directoryPath}/班级2/实验1/实验1_2022001_赵六.xlsx` },
      { name: '实验1_2022002_钱七.csv', path: `${directoryPath}/班级2/实验1/实验1_2022002_钱七.csv` },
      { name: '实验2_2022001_赵六.xls', path: `${directoryPath}/班级2/实验2/实验2_2022001_赵六.xls` },
      { name: '实验错误_2021004_不规范.txt', path: `${directoryPath}/班级1/实验1/实验错误_2021004_不规范.txt` },
      { name: '实验1_2021099_未知学生.xlsx', path: `${directoryPath}/班级1/实验1/实验1_2021099_未知学生.xlsx` }
    ];

    // 解析文件并检查异常
    const result = this.parseFiles(mockFiles, students);

    return result;
  }

  /**
   * 解析文件并检查异常
   * @param {Array} files - 文件列表
   * @param {Array} students - 学生列表
   * @returns {Object} 解析结果
   */
  static parseFiles(files, students) {
    const result = {
      files: [],
      exceptions: {
        invalidFormat: [],
        unknownStudent: []
      }
    };

    // 学生ID映射，用于快速查找
    const studentMap = new Map();
    students.forEach(student => {
      studentMap.set(student.studentId, student);
    });

    // 解析每个文件
    files.forEach(file => {
      try {
        // 检查文件名格式
        const fileInfo = this.parseFileName(file.name);

        if (!fileInfo) {
          // 文件名格式不正确
          result.exceptions.invalidFormat.push(file);
          logger.warn(`文件名格式不正确: ${file.name}`);
          return;
        }

        // 检查学生是否存在
        if (!studentMap.has(fileInfo.studentId)) {
          // 学生不在名单中
          result.exceptions.unknownStudent.push({
            file,
            parsedInfo: fileInfo
          });
          logger.warn(`学生不在名单中: ${fileInfo.studentId} (${fileInfo.studentName})`);
          return;
        }

        // 文件有效，添加到结果中
        result.files.push({
          ...file,
          parsedInfo: fileInfo
        });
      } catch (error) {
        logger.error(`解析文件失败: ${file.name}`, error);
        result.exceptions.invalidFormat.push(file);
      }
    });

    // 记录异常统计
    if (result.exceptions.invalidFormat.length > 0) {
      logger.warn(`发现 ${result.exceptions.invalidFormat.length} 个文件名格式不正确`);
    }

    if (result.exceptions.unknownStudent.length > 0) {
      logger.warn(`发现 ${result.exceptions.unknownStudent.length} 个学生不在名单中`);
    }

    return result;
  }

  /**
   * 解析文件名
   * @param {string} fileName - 文件名
   * @returns {Object|null} 解析结果，如果格式不正确则返回null
   */
  static parseFileName(fileName) {
    // 文件名格式：实验X_学号X_姓名X.xlsx|xls|csv
    const regex = /^实验(\d+|[一二三四五六七八九十]+)_(\w+)_(.+)\.(xlsx|xls|csv)$/;
    const match = fileName.match(regex);

    if (!match) {
      return null;
    }

    return {
      experimentName: `实验${match[1]}`,
      experimentNumber: match[1],
      studentId: match[2],
      studentName: match[3],
      fileExtension: match[4]
    };
  }

  /**
   * 获取目录结构
   * @param {string} directoryPath - 目录路径
   * @returns {Object} 目录结构
   */
  static async getDirectoryStructure(directoryPath) {
    try {
      logger.info(`获取目录结构: ${directoryPath}`);

      // 模拟目录结构
      // 在实际应用中，这里应该通过API获取目录结构
      const structure = {
        name: '课程',
        type: 'directory',
        children: [
          {
            name: '班级1',
            type: 'directory',
            children: [
              {
                name: '实验1',
                type: 'directory',
                children: [
                  { name: '实验1_2021001_张三.xlsx', type: 'file' },
                  { name: '实验1_2021002_李四.xlsx', type: 'file' },
                  { name: '实验1_2021003_王五.xlsx', type: 'file' }
                ]
              },
              {
                name: '实验2',
                type: 'directory',
                children: [
                  { name: '实验2_2021001_张三.xlsx', type: 'file' },
                  { name: '实验2_2021002_李四.xls', type: 'file' }
                ]
              },
              {
                name: '实验3',
                type: 'directory',
                children: [
                  { name: '实验3_2021001_张三.csv', type: 'file' }
                ]
              }
            ]
          },
          {
            name: '班级2',
            type: 'directory',
            children: [
              {
                name: '实验1',
                type: 'directory',
                children: [
                  { name: '实验1_2022001_赵六.xlsx', type: 'file' },
                  { name: '实验1_2022002_钱七.csv', type: 'file' }
                ]
              },
              {
                name: '实验2',
                type: 'directory',
                children: [
                  { name: '实验2_2022001_赵六.xls', type: 'file' }
                ]
              }
            ]
          }
        ]
      };

      return structure;
    } catch (error) {
      logger.error('获取目录结构失败', error);
      throw error;
    }
  }
}

export default ReportDirectoryScanner;
